package com.wits.qso.web.controller;

import java.io.File;
import java.io.FileInputStream;
import java.util.Arrays;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.UUID;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import javax.validation.Valid;

import org.apache.commons.io.FilenameUtils;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.shiro.authc.credential.PasswordService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.DataAccessException;
import org.springframework.data.domain.Page;
import org.springframework.stereotype.Controller;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.ui.Model;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartFile;
import org.springside.modules.web.Servlets;

import com.wits.platform.common.constants.UserType;
import com.wits.platform.common.constants.ViewType;
import com.wits.platform.common.constants.WebConstants;
import com.wits.platform.common.utils.FileUtil;
import com.wits.platform.common.utils.PageUtil;
import com.wits.platform.common.utils.StringUtil;
import com.wits.platform.entity.User;
import com.wits.platform.service.UserService;
import com.wits.platform.web.controller.BaseController;
import com.wits.platform.web.mvc.PageParam;
import com.wits.qso.entity.Cls;
import com.wits.qso.entity.Student;
import com.wits.qso.service.ClsService;
import com.wits.qso.service.DeptService;
import com.wits.qso.service.GradeService;
import com.wits.qso.service.StudentService;
import com.wits.qso.service.VmUserService;


@Controller
@RequestMapping(value = "qso/student")
public class StudentController extends BaseController
{

	private static final String ATTRIBUTE_STUDENT_BATCH_FILE = "studentBatchFile";
	/**
	 * 注入studentService
	 */
	@Autowired
	private StudentService stuService;

	/**
	 * 注入userService
	 */
	@Autowired
	private UserService userService;
	@Autowired
	private ClsService clsService;
	@Autowired
	private GradeService gradeService;
	@Autowired
	private DeptService deptService;
	@Autowired
	private PasswordService passwordService;
	
	@Autowired
	private VmUserService vmUserService;

	@RequestMapping(value = "/toList")
	public String toList() {
		return "qso/student/list";
	}

	/**
	 * 加载学生列表信息
	 * 
	 * @param model
	 * @param page
	 * @param req
	 * @return
	 */
	@RequestMapping(value = "/list")
	@ResponseBody
	public String list(Model model, @ModelAttribute("page")
	PageParam page, HttpServletRequest req) {
		Map<String, Object> searchParams = Servlets.getParametersStartingWith( req, "search_" );
		Page<Student> listPage = stuService.findPage( Student.class, searchParams, page );
		model.addAttribute( "searchParams", Servlets.encodeParameterStringWithPrefix( searchParams, "search_" ) );
		return PageUtil.toAjaxPageResult( listPage.getTotalElements(), listPage.getContent() );
	}

	/**
	 * 学生列表上按钮的触发事件处理
	 * 
	 * @param model
	 * @param viewType
	 * @param stuId
	 * @return
	 */
	@RequestMapping(value = "/view/{viewType}")
	public String toView(Model model, @PathVariable
	String viewType, @RequestParam
	String stuId) {
		if (ViewType.Add.getView().equals( viewType )) {
			model.addAttribute( WebConstants.COMMAND, new Student() );
			model.addAttribute("cla", new Cls());
		} else {
			Student stu= stuService.getOne( stuId );
			model.addAttribute( WebConstants.COMMAND, stu );
			model.addAttribute("cla", clsService.getOne(stu.getClsId()));
		}
		model.addAttribute( "clses", clsService.findAll() );
		model.addAttribute("grades", gradeService.findAll());
		model.addAttribute("depts", deptService.findAll());
		
		model.addAttribute( "viewType", viewType );
		return "qso/student/form";
	}

	@RequestMapping(value = "/info")
	public String toInfo(Model model) {
		Student stu = stuService.findByUserId( getCurrentUserId() );
		if (stu != null){
			model.addAttribute( WebConstants.COMMAND, stuService.getOne( stu.getStuId() ) );
			model.addAttribute("cls", clsService.getOne(stu.getClsId()));
			model.addAttribute("vmuser", vmUserService.findByUserId(getCurrentUserId()));
		}
		return "qso/student/info";
	}

	/**
	 * 修改密码
	 * 
	 * @param model
	 * @param terId
	 * @return
	 */
	@RequestMapping(value = "/changepwd")
	public Object chagePwd(Model model, @RequestParam
	String stuUserId) {
		model.addAttribute( WebConstants.COMMAND, stuService.getUser( stuUserId ) );
		return "qso/student/changepwd";
	}

	/**
	 * 新增、修改学生信息
	 * 
	 * @param model
	 * @param command
	 * @param viewType
	 * @param result
	 * @param req
	 * @return
	 */
	@RequestMapping(value = "/save", method = { RequestMethod.POST })
	@ResponseBody
	public Object save(Model model, @ModelAttribute("command")
	@Valid
	Student command, @RequestParam
	String viewType, BindingResult result, HttpServletRequest req) {
		if (result.hasErrors()) {
			model.addAttribute( WebConstants.COMMAND, command );
			return toView( model, viewType, command.getStuId() );
		}
		User user=null;
		if (ViewType.Add.getView().equals( viewType )) {
			command.setDateCre( new Date() );
			command.setUserCre( getCurrentUserId() );

			try {
				user = new User();
				user.setUserId( command.getStuUserId() );
				user.setUserNameC( command.getStuName() );
				user.setDateExpire( command.getDateExpire() );
				user.setIsEnable( "T" ); // 设置为true
				user.setUsertype( UserType.STUDENT.getValue() );
				String encrypted = passwordService.encryptPassword( "123456" );
				user.setUserPassword( encrypted ); // 初始密码为123456
				user.setUserCre( getCurrentUserId() );
				user.setUserEmail( command.getStuMail() );
				user.setDateCre( new Date() );

				if (userService.isExist( user )) {
					return ajaxDoneError( "登录账号已存在" );
				} else {
					stuService.save( command );
					userService.saveCascade( user ); // 保存到wits_user表
					return ajaxDoneSuccess( this.getText( "save.success" ) );
				}
			} catch (Exception e) {
				return ajaxDoneError( this.getText( "save.failed" ) );
			}
		} else {
			Student stu = stuService.getOne( command.getStuId() );
			command.setDateUpd( new Date() );
			command.setUserUpd( getCurrentUserId() );
			command.setDateCre( stu.getDateCre() );
			command.setUserCre( stu.getUserCre() );
			user=userService.getOne(command.getStuUserId());
			user.setUserNameC(command.getStuName());
			user.setDateExpire(command.getDateExpire());
			try {
				stuService.save( command );
				userService.save(user);
				return ajaxDoneSuccess( this.getText( "save.success" ) );
			} catch (Exception e) {
				return ajaxDoneError( this.getText( "save.failed" ) );
			}
		}

	}

	/**
	 * 删除学生信息
	 * 
	 * @param ids
	 * @return
	 */
	@RequestMapping(value = "/delete")
	@ResponseBody
	@Transactional(readOnly=false,rollbackFor=DataAccessException.class)
	public Object delete(String ids) {
		boolean hasSusscesed = false;
		boolean hasErrored = false;
		List<String> idList = null;
		try {

			idList = Arrays.asList( StringUtil.split( ids, "," ) );

			for (String id : idList) {
				try {
					Student stu=stuService.getOne(id);
					userService.delete(stu.getStuUserId());
					stuService.delete(id);
					hasSusscesed = true;
				} catch (Exception e) {
					hasErrored = true;
					throw new DataAccessException("有些被引用的学生无法删除") {
					};
				}
			}
			if (hasSusscesed) {
				if (hasErrored) {
					return ajaxDoneError( "有些被引用的学生无法删除" );
				} else {
					return ajaxDoneSuccess( this.getText( "delete.success" ) );
				}
			} else {
				return ajaxDoneError( "该学生已经被引用，无法删除" );
			}
		} catch (Exception e) {
			return ajaxDoneError( this.getText( "delete.failed" ) );
		}
	}

	@RequestMapping(value = "/import")
	public String importData(Model model) {
		return "qso/student/import";
	}

	@RequestMapping(value = "/import/save", method = { RequestMethod.POST })
	@ResponseBody
	public Object importData(Model model, HttpSession session) {
		int result = 0;
		String uploadFile = (String) session.getAttribute( ATTRIBUTE_STUDENT_BATCH_FILE );
		try {
			if (null != uploadFile) {
				result = stuService.batchStudentData( new HSSFWorkbook( new FileInputStream( new File( session.getServletContext().getRealPath( "/" ) + uploadFile ) ) ), getCurrentUserId() );
				logger.info(" success : {}", result);
			}
			return ajaxDoneSuccess( this.getText( "save.success" ) );
		} catch (Throwable cause) {
			logger.info( cause.getMessage(), cause );
			return ajaxDoneError( this.getText( "save.failed" ) );
		}
	}

	@RequestMapping(value = "/import/upload")
	public void importDataUpload(@RequestParam(value = "attachment") MultipartFile multipartFile, HttpSession session) {
		String extension = FilenameUtils.getExtension( multipartFile.getOriginalFilename() );
		String uuid = UUID.randomUUID().toString().replace( "-", "" );
		String storagePath = WebConstants.UPLOAD_DIR + File.separator + "import" + File.separator + uuid;

		try {
			FileUtil.upload( multipartFile, session.getServletContext().getRealPath( "/" ) + storagePath, uuid + "." + extension );
			session.setAttribute( ATTRIBUTE_STUDENT_BATCH_FILE, storagePath + File.separator + uuid + "." + extension );
		} catch (Throwable cause) {
			logger.error( cause.getMessage(), cause );
		}
	}

	@RequestMapping(value = "/message")
	public String message(Model model) {
		model.addAttribute( WebConstants.COMMAND, stuService.findByUserId( getCurrentUserId() ) );

		return "qso/student/message";
	}
}
